package com.iteaj.iot.modbus.server.dtu;

import com.iteaj.iot.ProtocolType;
import com.iteaj.iot.modbus.consts.ModbusCode;
import com.iteaj.iot.modbus.consts.ModbusErrCode;
import com.iteaj.iot.server.dtu.DefaultDtuMessageAware;
import com.iteaj.iot.server.dtu.DtuCommonProtocolType;
import io.netty.buffer.ByteBuf;

public class ModbusRtuMessageAware<M extends ModbusRtuForDtuMessage> extends DefaultDtuMessageAware<M> {

    @Override
    protected ProtocolType customizeType(String equipCode, byte[] message, ByteBuf msg) {
        // modbus rtu 协议报文长度不能小于2
        // 小于2说明是dtu的报文
        if(message.length < 2) {
            return DtuCommonProtocolType.DTU;
        }

        // 获取modbus tcp的功能码
        int code = message[1] & 0xFF;
        if(code > 0x80) { // 读取到的功能码可能是modbus的异常码, 异常码大于 0x80
            code = code - 0x80;
            try {
                ModbusCode.INSTANCE((byte) code);
                ModbusErrCode.valueOf(message[2]);
                return null;
            } catch (IllegalStateException e) {
                return DtuCommonProtocolType.DTU;
            }
        }

        // modbus的功能码只能是在 0x01 - 0x10之间
        if(code >= 0x01 && code <= 0x10) {
            try {
                ModbusCode.INSTANCE((byte) code);
                if(code <= 0x04) { // 读报文校验
                    byte length = message[2];
                    if(message.length < length + 5) {
                        return DtuCommonProtocolType.DTU;
                    }
                } else { // 写报文校验
                    if(message.length < 8) {
                        return DtuCommonProtocolType.DTU;
                    }
                }
            } catch (IllegalStateException e) { // 不是modbus协议的功能码
                return DtuCommonProtocolType.DTU;
            }
        } else { // 不存在功能码说明不是modbus协议
            return DtuCommonProtocolType.DTU;
        }
        return super.customizeType(equipCode, message, msg);
    }
}
